/*
 * Copyright (C) ${year} Jeffrey Palm.
 *
 * This code is part of the Floto Project (http://jeffpalm.com/floto/).
 * Please consult the LICENSE included in the distribution.
 */
package com.jeffpalm.floto.isight;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.jeffpalm.floto.isight.util.Util;

public final class Main extends AbstractMain {

  private SplashWindow sw;

  public static void main(String[] args) {
    new Main().realMain(args);
  }

  protected Main() {
    super(Depot.getInstance());
  }

  public void realMain(String[] args) {
    mainLoop();
    shutDown();
  }

  private void showCountDown() {
    splashScreen();
    for (int i = 3; i > 0; i--) {
      sw.setStatus("Starting in " + i + "...");
      try {
        Thread.sleep(1000);
      } catch (InterruptedException _) {}
    }
  }

  private void mainLoop() {
    while (true) {
      showCountDown();
      BufferedImage img = captureWebcamShot();
      int keep = keepImage(img);
      if (keep == JOptionPane.YES_OPTION) {
        if (publish(img)) break;
      } else if (keep == JOptionPane.CANCEL_OPTION) {
        break;
      } else /* NO */ {}
    }
  }
  
  private JLabel headerLabel(String msg) {
    JLabel res = new JLabel(msg + "\n");
    res.setFont(new Font(res.getFont().getName(), Font.BOLD, 16));
    return res;
  }
  
  private JPanel optionPanel(String msg) {
    JPanel res = new JPanel();
    res.add(headerLabel(msg));
    res.setLayout(new BoxLayout(res, BoxLayout.Y_AXIS));
    res.add(Box.createVerticalGlue());
    return res;
  }
  
  private int addYesNoCancelOptions(String title, JPanel msg) {
    msg.add(new JLabel("\nSelect"));
    msg.add(new JLabel(" - 'Yes' to publish,"));
    msg.add(new JLabel(" - 'No' to take another, or"));
    msg.add(new JLabel(" - 'Cancel' to quit"));
    return JOptionPane.showConfirmDialog(null, msg, title, JOptionPane.YES_NO_CANCEL_OPTION,
        JOptionPane.QUESTION_MESSAGE);    
  }
  
  private JTextField labeledTextField(String label, JPanel p) {
    return labeledTextField(label,p,null);
  }
  
  private JTextField labeledTextField(String label, JPanel p, String text) {
    JTextField res = new JTextField(30);
    if (text != null) res.setText(text);
    p.add(new JLabel(label));
    p.add(res);
    return res;
  }
  
  private String addParam(String url, String name, String value) {
    if (Util.isEmpty(value)) return url;
    char sep = url.indexOf('?') == -1 ? '?' : '&';
    try {
      return url + sep + name + '=' + URLEncoder.encode(value, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      handle(e);
    }
    return url + sep + name + '=' + value.replace(' ','+');
  }
  
  /**
   * @param img image to publish
   * @return <code>true</code> if we either publish or want to quit
   */
  private boolean publish(BufferedImage img) {
    note("Publishing " + img);
    JPanel msg = optionPanel("Publish photo");
    JPanel p = new JPanel();
    p.setLayout(new BoxLayout(p,BoxLayout.Y_AXIS));
    JTextField urlField = labeledTextField("Post URL", msg, getConfig().get(ConfigInstance.Props.POST_URL));
    JTextField locField = labeledTextField("Location", msg, getConfig().get(ConfigInstance.Props.DEFAULT_LOCATION));
    JTextField desField = labeledTextField("Description", msg);
    JTextField latField = labeledTextField("Latitude", msg);
    JTextField lngField = labeledTextField("Longitude", msg);
    int res = addYesNoCancelOptions("Publish photo", msg);
    if (res == JOptionPane.OK_OPTION) {
      String url = urlField.getText().trim();
      String loc = locField.getText().trim();
      String des = desField.getText().trim();
      String lat = latField.getText().trim();
      String lng = lngField.getText().trim();
      if (Util.isEmpty(url)) getConfig().set(ConfigInstance.Props.POST_URL, url);
      if (Util.isEmpty(loc)) getConfig().set(ConfigInstance.Props.DEFAULT_LOCATION, loc);
      url = addParam(url, "location",     loc);
      url = addParam(url, "description",  des);
      url = addParam(url, "lat",          lat);
      url = addParam(url, "lng",          lng);
      note("Publishing to " + url);
      sendPhoto(url,img,getClass().getSimpleName() + ".jpg");
      JPanel c = new JPanel();
      c.add(new JLabel("Photo uploaded!"));
      showConfirm(c, "Photo uploaded!");
      return true;
    } else if (res == JOptionPane.CANCEL_OPTION) {
      return true;
    }
    return false;
  }

  private int keepImage(BufferedImage img) {
    note("Displaying " + img);
    JPanel msg = optionPanel("Should we publish this photo?");
    msg.add(new JLabel(new ImageIcon(resizeImage(img))));
    return addYesNoCancelOptions("Publish", msg);
  }
  
  private Image resizeImage(BufferedImage img) {
    ImageIcon ii = new ImageIcon(img);
    Image i = ii.getImage();
    int iWidth = i.getWidth(null);
    int iHeight = i.getHeight(null);
    int newWidth = iWidth/2;
    int newHeight = iHeight/2;
    return i.getScaledInstance(newWidth,newHeight,Image.SCALE_SMOOTH);
    
  }

  private void shutDown() {
    if (sw != null) sw.dispose();
    sw = null;
    getConfig().saveOptions();
  }

  private void splashScreen() {
    sw = new SplashWindow();
  }

}
